"""
FileName：conftest.py
Description：
Author：gaojiahui
Time：2025/8/18 20:10
Website：https://gitee.com/gao-jiahui
"""
import time

import allure
import pytest

from core.auth_manager import auth_manager
from core.db_client import DBClient
from core.logger import logger
from utils.notifier import notifier

#  全局变量存储测试结果
_test_results = {
    "start_time": 0.0,
    "end_time": 0.0,
    "total": 0,
    "passed": 0,
    "failed": 0,
    "skipped": 0,
    "failed_cases": []
}

def pytest_configure(config):
    """pytest配置钩子"""
    _test_results["start_time"] = time.time()

def pytest_unconfigure(config):
    """pytest结束钩子"""
    _test_results["end_time"] = time.time()
    _test_results["duration"] = float(_test_results["end_time"] - _test_results["start_time"])

    # 发送测试报告
    if notifier.enabled:
        logger.info("发送测试报告通知...")
        notifier.send_test_report(_test_results)

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """
    统一的测试报告钩子函数，处理Allure报告和通知数据收集
    """
    outcome = yield
    report = outcome.get_result()

    # 添加类型检查保护
    if not hasattr(item, 'nodeid') or not isinstance(item.nodeid, str):
        logger.warning(f"Invalid test item: {item}")
        return

    # 更新测试结果统计
    if report.when == "call":
        _test_results["total"] += 1

        if report.outcome == "passed":
            _test_results["passed"] += 1
        elif report.outcome == "failed":
            _test_results["failed"] += 1
            # 记录失败用例信息
            _test_results["failed_cases"].append({
                "name": item.name,
                "nodeid": item.nodeid,
                "reason": str(report.longrepr) if report.longrepr else "未知原因"
            })
        elif report.outcome == "skipped":
            _test_results["skipped"] += 1

        allure.attach(
            str(report),
            name="pytest_report",
            attachment_type=allure.attachment_type.JSON
        )

    # 处理Allure报告附件
    if report.failed and hasattr(item, 'funcargs'):
        driver = item.funcargs.get('driver')
        if driver:
            # 截取屏幕截图并附加到Allure报告
            try:
                screenshot = driver.get_screenshot_as_png()
                allure.attach(
                    screenshot,
                    name="screenshot",
                    attachment_type=allure.attachment_type.PNG
                )
            except Exception as e:
                logger.error(f"截图失败: {str(e)}")

@pytest.fixture(scope="session", autouse=True)
def init_auth():
    """session级别初始化认证"""
    auth_manager.get_token()  # 整个测试会话只执行一次
    yield
    # 可选的清理逻辑（如需要可添加登出操作）

@pytest.fixture(scope="session", autouse=True)
def setup_suite():
    logger.info("\n===== 测试套件开始 =====")
    yield
    logger.info("\n===== 测试套件结束 =====")

@pytest.fixture(scope="function")
def db_client():
    db = DBClient()
    yield db
    db.close()

@pytest.fixture(scope="class")
def admin_token():
    return auth_manager.token

@pytest.fixture(scope="function")
def create_test_data():
    """创建测试数据并返回，测试后清理"""
    test_data = {}
    yield test_data
    # 这里实际项目中会有数据清理逻辑
